import { Button, NavBar, Form, Input } from 'antd-mobile';

import styles from './index.module.scss';

import { Toast } from 'antd-mobile';
import { useHistory } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { login,getCode } from '@/store/actions';
import { AxiosError } from 'axios';

import { useEffect, useRef } from 'react'
import { InputRef } from 'antd-mobile/es/components/input'


import  {useState} from 'react'

type LoginForm = {
  mobile: string;
  code: string;
};

const Login = () => {

 // 创建 form 实例
 const [form] = Form.useForm();

  const dispatch = useDispatch();
  const history = useHistory();

  const onFinish = async (values: LoginForm) => {
    // console.log(values)
    try {
      await dispatch(login(values));
      //  登录成功提示
      Toast.show({
        content: '登录成功',
        duration: 600,
        afterClose: () => {
          //返回首页
          history.replace('/home');
        },
      });
    } catch (e) {
    // 异常
    // 如果异步操作失败了，会执行此处的错误处理
    // 对于登录功能来说，出错了，通常是请求出问题了。
    // 因此，此处将错误类型转为 AxiosError

    const error= e as AxiosError<{messsage:string}>
       Toast.show({
        content: error.response?.data?.messsage,
        duration:1000
       })

    } 
  };



  const timerRef = useRef(-1);  // 存储定时器

  const [time, setTime] = useState(0);
  const mobileRef = useRef<InputRef>(null)
  const onGetCode=()=>{
     // 拿到手机号
     let  mobile= (form.getFieldValue('mobile')??'') as string   
     // 判断手机号校验是否成功
     const hasError = form.getFieldError('mobile').length > 0
     if (mobile.trim() === '' || hasError) {
       return mobileRef.current?.focus()
     }
     // 表单验证成功，获取验证码
    // 发送请求，根据 手机号 来获取验证码
      dispatch(getCode(mobile)  as  any)
      setTime(5);

       // 注意：此处需要使用 window.setInterval
  // 因为 setInterval 默认返回 NodeJS.Timeout，使用 window.setInterval 后，返回值才是 number 类型的数值
    timerRef.current= window. setInterval(()=>{
        setTime((time)=>time-1)
      },1000)
  }
// 1. 监听倒计时变化，在倒计时结束时清理定时器
useEffect(()=>{
  if(time===0) {
      clearInterval(timerRef.current)
  }
},[time])

// 2. 在组件卸载时清理定时器
 useEffect(()=>{
return ()=>{
     // 组件卸载时清理定时器
     clearInterval(timerRef.current);
}

 },[])



  return (
    <div className={styles.root}>
      <NavBar></NavBar>
      <div className="login-form">
        <h2 className="title"> 账号登录</h2>
        <Form validateTrigger={['onBlur']} onFinish={onFinish}    form={form}>
          <Form.Item
            className="login-item"
            name="mobile"
            validateTrigger="onBlur"
            rules={[
              { required: true, message: '请输入手机号' },
              { pattern: /^1[3-9]\d{9}$/, message: '手机号格式错误' },
            ]}
          >
            <Input type="text" placeholder="请输入手机号"  maxLength={11} ref={mobileRef}/>
          </Form.Item>

          <Form.Item
            className="login-item"
            name="code"
            rules={[{ required: true, message: '请输入验证码' }]}
            validateTrigger="onBlur"
            extra={<span className="code-extra"

               // 判断是否开启定时器，没开启绑定事件，开启后去掉事件
            onClick={time === 0 ? onGetCode : undefined}
            
            >  
             {/* 判断是否开启定时器，没开启展示 发送验证码，开启后展示倒计时 */}
             {time===0?  '发送验证码': `${time}s后重新获取`}
            </span>}
          >
            <Input type="text" placeholder="请输入验证码" autoComplete="off" />
          </Form.Item>
          {/* noStyle 表示不提供 Form.Item 自带的样式 */}
          <Form.Item noStyle  shouldUpdate>

     {
      ()=>{
             // isFieldsTouched(true) 检查是否所有字段都被操作过
          const untouched = !form.isFieldsTouched(true);
             const hasError =
             form.getFieldsError().filter(({ errors }) => errors.length)
               .length !== 0;
           const disabled = untouched || hasError;

         return ( <Button
          block
          type="submit"
          color="primary"
          className="login-submit"
          disabled={disabled}
        >
          登录
        </Button>)
      }
     }

           
          </Form.Item>
        </Form>
      </div>
    </div>
  );
};

export default Login;
